package ca.uqac.dim.turtledb.physical;

import ca.uqac.dim.turtledb.CentralizedCommunicator;
import ca.uqac.dim.turtledb.Communicator;
import ca.uqac.dim.turtledb.QueryOptimizer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * User: damien
 * Date: 12-12-02
 * Time: 02:19
 * <p/>
 * Design Pattern : Context
 * <p/>
 * Context for physical Elements
 * <p/>
 * Contains a Graph where Site are nodes and Link are arcs
 * Implemented with a List of Sites
 */
public class Network {
    private Map<String, Site> sites = new HashMap<String, Site>();
    private QueryOptimizer queryOptimizer;

    public List<Site> getSites() {
        return new ArrayList<Site>(sites.values());
    }

    public void addSite(Site site) {
        sites.put(site.getName(), site);
        site.setNetwork(this);
    }

    public void addSites(List<Site> sites) {
        for (Site site : sites) {
            site.setNetwork(this);
            this.sites.put(site.getName(), site);
        }
    }

    public Link link(Site site1, Site site2, int cost) {
        addSite(site1);
        addSite(site2);
        return new Link(site1, site2, cost);
    }

    public Site getSiteForName(String name) {
        return sites.get(name);
    }

    public CentralizedCommunicator createCommunicator() {
        CentralizedCommunicator communicator = new CentralizedCommunicator();
        for(Site site : sites.values()) {
            communicator.addSite(site.getLocalEngine());
        }
        return communicator;

    }

    public QueryOptimizer getQueryOptimizer() {
        if(queryOptimizer == null)                 {
            queryOptimizer = new QueryOptimizer();
            queryOptimizer.setNetwork(this);
        }
        return queryOptimizer;
    }

    public abstract static class NetworkMember {

        private Network localNetwork;

        protected Network getNetwork() {
            return localNetwork;
        }

        protected void setNetwork(Network network) {
            localNetwork = network;
        }
    }
}
